﻿using System;
using System.Collections.Generic;
using System.Web.Services;
using Subgurim.Controles;
using CounterServerModel;
using CounterServerModel.Authentication;

namespace SmartCounters.WebServices
{
    /// <summary>
    /// This is a Web Service that represents the Information Updater in the model of the system.
    /// </summary>
    [WebService(Namespace = "http://smartcounters.org")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class InformationUpdaterWebService : WebService
    {
        [WebMethod]
        public int CreateAccountWithoutApartment(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            string i_Country,
            string i_City,
            string i_Street,
            int i_House,
            string i_Phone,
            string i_UsersAssociatedWith)
        {
            GLatLng latLng = this.GetCoordinatedByAddress(i_Country, i_City, i_Street, i_House);
            double longitude = latLng.lng;
            double latitude = latLng.lat;
            string[] users = i_UsersAssociatedWith.Substring(1).Substring(0, i_UsersAssociatedWith.Length - 2).Split(',');
            
            List<int> usersAssociatedWith = new List<int>();
            if (!(users.Length == 1 && users[0].Length == 0))
            {
                foreach (string userID in users)
                {
                    usersAssociatedWith.Add(int.Parse(userID));
                }
            }

            return new InformationUpdater().CreateAccount(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new AccountInfo()
            {
                Country = i_Country,
                City = i_City,
                Street = i_Street,
                House = i_House,
                Apartment = null,
                Phone = i_Phone,
                Longitude = longitude,
                Latitude = latitude,
                UsersAssociatedWith = usersAssociatedWith
            });
        }

        [WebMethod]
        public int CreateAccountWithApartment(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            string i_Country,
            string i_City,
            string i_Street,
            int i_House,
            int i_Apartment,
            string i_Phone,
            string i_UsersAssociatedWith)
        {
            GLatLng latLng = this.GetCoordinatedByAddress(i_Country, i_City, i_Street, i_House);
            double longitude = latLng.lng;
            double latitude = latLng.lat;
            string[] users = i_UsersAssociatedWith.Substring(1).Substring(0, i_UsersAssociatedWith.Length - 2).Split(',');

            List<int> usersAssociatedWith = new List<int>();
            if (!(users.Length == 1 && users[0].Length == 0))
            {
                foreach (string userID in users)
                {
                    usersAssociatedWith.Add(int.Parse(userID));
                }
            }

            return new InformationUpdater().CreateAccount(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new AccountInfo()
            {
                Country = i_Country,
                City = i_City,
                Street = i_Street,
                House = i_House,
                Apartment = i_Apartment,
                Phone = i_Phone,
                Longitude = longitude,
                Latitude = latitude,
                UsersAssociatedWith = usersAssociatedWith
            });
        }

        [WebMethod]
        public void DeleteAccount(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_AccountID)
        {
            new InformationUpdater().DeleteAccount(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), i_AccountID);
        }

        [WebMethod]
        public int CreateUser(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            string i_Username,
            int i_UserPermissions,
            string i_Phone,
            string i_MobilePhone,
            string i_Email,
            string i_Password,
            string i_AccountsAssociatedWith)
        {
            string[] accounts = i_AccountsAssociatedWith.Substring(1).Substring(0, i_AccountsAssociatedWith.Length - 2).Split(',');

            List<int> accountsAssociatedWith = new List<int>();
            if (!(accounts.Length == 1 && accounts[0].Length == 0))
            {
                foreach (string userID in accounts)
                {
                    accountsAssociatedWith.Add(int.Parse(userID));
                }
            }

            return new InformationUpdater().CreateUser(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new UserInfo()
            {
                Username = i_Username,
                UserPermissions = (eUserPermissions)i_UserPermissions,
                Phone = i_Phone,
                MobilePhone = i_MobilePhone,
                Email = i_Email,
                Password = i_Password,
                AccountsAssociatedWith = accountsAssociatedWith
            });
        }

        [WebMethod]
        public void DeleteUser(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_UserID)
        {
            new InformationUpdater().DeleteUser(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), i_UserID);
        }

        [WebMethod]
        public void UpdateAccountWithoutApartment(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            int i_AccountID,
            string i_Country,
            string i_City,
            string i_Street,
            int i_House,
            string i_Phone,
            string i_UsersAssociatedWith)
        {
            GLatLng latLng = this.GetCoordinatedByAddress(i_Country, i_City, i_Street, i_House);
            double longitude = latLng.lng;
            double latitude = latLng.lat;
            string[] users = i_UsersAssociatedWith.Substring(1).Substring(0, i_UsersAssociatedWith.Length - 2).Split(',');

            List<int> usersAssociatedWith = new List<int>();
            if (!(users.Length == 1 && users[0].Length == 0))
            {
                foreach (string userID in users)
                {
                    usersAssociatedWith.Add(int.Parse(userID));
                }
            }

            new InformationUpdater().UpdateAccount(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new AccountInfo()
            {
                AccountID = i_AccountID,
                Country = i_Country,
                City = i_City,
                Street = i_Street,
                House = i_House,
                Apartment = null,
                Phone = i_Phone,
                Longitude = longitude,
                Latitude = latitude,
                UsersAssociatedWith = usersAssociatedWith
            });
        }

        [WebMethod]
        public void UpdateAccountWithApartment(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            int i_AccountID,
            string i_Country,
            string i_City,
            string i_Street,
            int i_House,
            int i_Apartment,
            string i_Phone,
            string i_UsersAssociatedWith)
        {
            GLatLng latLng = this.GetCoordinatedByAddress(i_Country, i_City, i_Street, i_House);
            double longitude = latLng.lng;
            double latitude = latLng.lat;
            string[] users = i_UsersAssociatedWith.Substring(1).Substring(0, i_UsersAssociatedWith.Length - 2).Split(',');

            List<int> usersAssociatedWith = new List<int>();
            if (!(users.Length == 1 && users[0].Length == 0))
            {
                foreach (string userID in users)
                {
                    usersAssociatedWith.Add(int.Parse(userID));
                }
            }

            new InformationUpdater().UpdateAccount(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new AccountInfo()
            {
                AccountID = i_AccountID,
                Country = i_Country,
                City = i_City,
                Street = i_Street,
                House = i_House,
                Apartment = i_Apartment,
                Phone = i_Phone,
                Longitude = longitude,
                Latitude = latitude,
                UsersAssociatedWith = usersAssociatedWith
            });
        }

        [WebMethod]
        public void UpdateUser(
            int i_AuthenticatedUserID,
            string i_AuthenticatedUserPassword,
            int i_UserID,
            string i_Username,
            int i_UserPermissions,
            string i_Phone,
            string i_MobilePhone,
            string i_Email,
            string i_Password,
            string i_AccountsAssociatedWith)
        {
            string[] accounts = i_AccountsAssociatedWith.Substring(1).Substring(0, i_AccountsAssociatedWith.Length - 2).Split(',');

            List<int> accountsAssociatedWith = new List<int>();
            if (!(accounts.Length == 1 && accounts[0].Length == 0))
            {
                foreach (string userID in accounts)
                {
                    accountsAssociatedWith.Add(int.Parse(userID));
                }
            }

            new InformationUpdater().UpdateUser(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new UserInfo()
            {
                ID = i_UserID,
                Username = i_Username,
                UserPermissions = (eUserPermissions)i_UserPermissions,
                Phone = i_Phone,
                MobilePhone = i_MobilePhone,
                Email = i_Email,
                Password = i_Password,
                AccountsAssociatedWith = accountsAssociatedWith
            });

        }

        [WebMethod]
        public void UpdateUsage(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_AccountID, double i_TotalUsage)
        {
            new InformationUpdater().UpdateUsage(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), i_AccountID, i_TotalUsage);
        }

        [WebMethod]
        public int CreateFault(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_AccountID, string i_Description)
        {
            return new InformationUpdater().CreateFault(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), i_AccountID, i_Description);
        }

        [WebMethod]
        public void UpdateFault(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_FaultID, int i_UserID, int i_AccountID, DateTime i_FaultDate, string i_Description, bool i_IsSolved)
        {
            new InformationUpdater().UpdateFault(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), new Fault()
            {
                FaultID = i_FaultID,
                UserID = i_UserID,
                AccountID = i_AccountID,
                FaultDate = i_FaultDate,
                Description = i_Description,
                IsSolved = i_IsSolved
            });
        }

        [WebMethod]
        public void SolveFault(int i_AuthenticatedUserID, string i_AuthenticatedUserPassword, int i_FaultID)
        {
            new InformationUpdater().SolveFault(new AuthenticatedUserCredentials(i_AuthenticatedUserID, i_AuthenticatedUserPassword), i_FaultID);
        }

        private GLatLng GetCoordinatedByAddress(string i_Country, string i_City, string i_Street, int i_House)
        {
            GMap gMapAccount = new GMap();
            gMapAccount.Key = "AIzaSyARmX9FYK0psugZwDZWZNPYdWKYJ6U-Hmc";

            string LocationInfo = string.Format("{0} {1} {2} {3}", i_Country, i_City, i_Street, i_House);

            GeoCode gCode = GMap.geoCodeRequest(LocationInfo, gMapAccount.Key);
            return new GLatLng(gCode.Placemark.coordinates.lat, gCode.Placemark.coordinates.lng);
        }
    }
}
